var tgd = tgd || {};
tgd.Tools = tgd.Tools || {};
tgd.Tools.ContactDiff = tgd.Tools.ContactDiff || {};

/*
 * name - STRING - name/path of the property
 * multi - BOOLEAN - can this property have multiple values per user?
 */
tgd.Tools.ContactDiff.Property = function (name, multi) {
	var _values = [];
	var _users = [];
	var _name = name;
	var _multi = multi;

	this.__defineGetter__("Values", function() { return _values; });
	this.__defineGetter__("Name", function() { return _name; });
	this.__defineGetter__("HasDiffs", function() { return (!_multi && _values.length > 1) || (_multi && _values.some(function(element, index, array) { return element.Users.length !== _users.length; })) });
	this.__defineGetter__("UserCount", function() { return _users.length; });
	this.__defineGetter__("Users", function() { return _users; });  //The users that have a value for this property
	this.__defineGetter__("ValueCount", function() { return _values.length; });
	this.__defineGetter__("AllowMultiples", function() { return _multi; });

	/*
	 * Check if [a] and [b] are "equal".
	 *
	 * a - any
	 * b - any
	 *
	 * return boolean
	 *		true: if @a and @b have identical properties with identical values
	 *		false: otherwise
	 */
	var isEqual = function(a, b) {
		if (a === undefined || b === undefined) {
			return false;
		} else if (typeof a === "string" || a === "number") {
			return a === b;
		} else if (a instanceof Array) {
			console.error("Assuming no arrays!", a, b);
		} else {  //object, check all properties for equality
			var allPropertiesMatch = true;

			for (var p in a) {
				if (!isEqual(a[p], b[p])) {
					allPropertiesMatch = false;
					break;
				}
			}

			for (var p in b) {
				if (!isEqual(b[p], a[p])) {
					allPropertiesMatch = false;
					break;
				}
			}

			return allPropertiesMatch;
		}
	}

	/*
	 * Add the [value] for the associated [user] to this property.
	 *
	 * return boolean
	 *      true: the value already existed
	 *		false: otherwise
	 */
	this.add = function(value, user) {
		var valExisted = false;

		var userExists = _users.some(function(element, index, array) { return element === user; });
		if (!userExists) {
			_users.push(user);
		}

		for (var i = 0; i < _values.length; ++i) {
			if (isEqual(_values[i].Value, value)) {
				_values[i].Users.push(user);
				valExisted = true;
				break;
			}
		}

		if (!valExisted) {
			_values.push( { Value : value, Users : [user] } );
		}

		return valExisted;
	}
}
